home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / SAT 2.4.0 / SAT / Add-ons / Graphic effects / GammaFade.p < prev    next >
Encoding:
Text File  |  1996-12-28  |  13.1 KB  |  429 lines  |  [TEXT/PJMM]

  1. unit GammaFade;
  2.  
  3. {--------------------------------------------------------------------------------------------------------------- }
  4. { File "gamma.p" - Source for Altering the Gamma Tables of GDevices from Gamma.c                                 }
  5. {   Last updated 6/29/95, MJS                                                                                     }
  6. {--------------------------------------------------------------------------------------------------------------- }
  7. {    7-13-95    ported to pascal  by Matthew Xavier Mora mxmora@mxmdesigns.com                                         }
  8. {     7-18-95     fixed all the porting bugs and got it to work in think pascal                                     }
  9. {----------------------------------------------------------------------------------------------------------------}
  10. {     7-18-95 ported to CW (68k and PPC) by Bill Catambay (pretty easy), cleaned the code a bit (no more labels),     }
  11. {           brought back Matthew's delay fade routines (in main program).                                             }
  12. {----------------------------------------------------------------------------------------------------------------}
  13. {    august -95: Change by Ingemar R: Moved the FadeToBlack and FadeFromBlack calls to}
  14. {        this unit and modified them to be timed by TickCount and aborted by mouse clicks.}
  15. {        DoGammaFade now auto-initializes - no call to SetupGammaTools is needed.}
  16. {        You can use FadeToBlack and FadeFromBlack only. They both check for gamma tables}
  17. {        to be available, so you don't have to call IsGammaAvailable yourself.}
  18. {        These changes were made when making a SAT add-on unit of it.}
  19.  
  20.  
  21. {---------------------------------------------------------------------------------------------------------------}
  22. {    This is the Source Code for the Gamma Utils Library file. Use this to build                                    }
  23. {        new functionality into the library or make an A4-based library.                                         }
  24. {    See the header file "gamma.h" for much more information. -- MJS                                                }
  25. {---------------------------------------------------------------------------------------------------------------}
  26.  
  27. interface
  28.  
  29.     uses
  30. {$IFC UNDEFINED THINK_PASCAL}
  31.         Types, QuickDraw, Fonts, Events, Packages, Menus, Dialogs, Windows,{}
  32.         OSUtils, ToolUtils, Resources, Memory, Devices, Files,
  33. {$ENDC}
  34.         Traps, Video;
  35.  
  36. { Function Prototypes}
  37.  
  38.     function IsGammaAvailable: Boolean;
  39.     function IsOneGammaAvailable (theGDevice: GDHandle): Boolean;
  40.  
  41. {    These routines help you determine whether you can use the Gamma Table Utils}
  42. {        on the current machine. The first checks all attached monitors, and the }
  43. {        second just checks the indicated monitor. Each returns TRUE if you can }
  44. {        use the functions, or FALSE if you can't. • Note: Before calling any other}
  45. {        Gamma Table function below, use this function to see if you are allowed.}
  46.  
  47. { * ****************************************************************************** *}
  48.  
  49.     function SetupGammaTools: OSErr;
  50.     function DisposeGammaTools: OSErr;
  51.  
  52. {    These routines must bracket any calls to the Gamma Table functions, perhaps}
  53. {        at the head and tail of your main(). The first sets up the data structures}
  54. {        necessary to save and restore the state of your monitors. The second}
  55. {        disposes of all the internal data structures, but does not reset the}
  56. {        monitors to their original states. Both return the error code if some}
  57. {        part failed. }
  58.  
  59. { * ****************************************************************************** *}
  60.  
  61.     function DoGammaFade (percent: Integer): OSErr;
  62.     function DoOneGammaFade (theGDevice: GDHandle; percent: Integer): OSErr;
  63.  
  64.  
  65. {    Use the first function to Fade each of your monitors to some percentage of their}
  66. {        initial brightness (100 = bright, 0 = dim). Repeatedly call this to ramp your}
  67. {        monitors up or down. The second function performs the same function, but only}
  68. {        for the specified monitor. Both return any applicable error codes.}
  69. {    Be sure to set up the necessary save-state data structures before you start by}
  70. {        calling the compatibility and initialization functions. }
  71.  
  72. { * ****************************************************************************** *}
  73.  
  74. {function GetDevGammaTable (theGDevice: GDHandle; var theTable: GammaTblPtr): OSErr;}
  75. {function SetDevGammaTable (theGDevice: GDHandle; var theTable: GammaTblPtr): OSErr;}
  76.  
  77.  
  78. {    These routines are low-level interfaces to the device drivers for the monitors.}
  79. {        Use them at your own risk.}
  80. {NO LONGER EXPORTED! /Ingemar}
  81.  
  82.  
  83. {Quick fixed-time calls:}
  84.  
  85.     procedure FadeToBlack (ticks: Longint);
  86.     procedure FadeFromBlack (ticks: Longint);
  87.  
  88.  
  89. implementation
  90.  
  91.     const
  92.         kGammaUtilsSig = 'GAMA';
  93.         kGetDeviceListTrapNum = $AA29;
  94.  
  95.     type
  96.         GlobalGammasPtr = ^GlobalGammas;
  97.         GlobalGammasHdl = ^GlobalGammasPtr;
  98.         GlobalGammas = record
  99.                 size, dataOffset: Integer;
  100.                 saved, hacked: GammaTblHandle;
  101.                 theGDevice: GDHandle;
  102.                 next: GlobalGammasHdl;
  103.             end;
  104.         GammaData = packed array[0..100000] of Byte;  {used to set the gamma}
  105.         GammaDataPtr = ^GammaData;
  106.  
  107.     var
  108.         gammaUtilsInstalled: OSType;
  109.         gammaTables: GlobalGammasHdl;
  110.  
  111.     function GetDevGammaTable (theGDevice: GDHandle; var theTable: GammaTblPtr): OSErr;
  112.     forward;
  113.     function SetDevGammaTable (theGDevice: GDHandle; var theTable: GammaTblPtr): OSErr;
  114.     forward;
  115.  
  116.  
  117.  
  118. {Fixed-time fading routines that can be aborted with a mouse click.}
  119.  
  120.     procedure FadeToBlack (ticks: Longint);
  121.         var
  122.             i: integer;
  123.             oe: OSErr;
  124.             startTicks: Longint;
  125.     begin
  126.         if not IsGammaAvailable then
  127.             Exit(FadeToBlack);
  128.         startTicks := TickCount;
  129.         while TickCount < startTicks + ticks do
  130.             begin
  131.                 i := 100 * (startTicks + ticks - TickCount) div ticks;
  132.                 oe := DoGammaFade(i);
  133.  
  134.                 if Button then
  135.                     begin
  136.                         oe := DoGammaFade(0);
  137.                         Exit(FadeToBlack);
  138.                     end;
  139.             end;
  140.         oe := DoGammaFade(0);
  141.     end; {FadeToBlack}
  142.  
  143.     procedure FadeFromBlack (ticks: Longint);
  144.         var
  145.             i: integer;
  146.             oe: OSErr;
  147.             startTicks: Longint;
  148.     begin
  149.         if not IsGammaAvailable then
  150.             Exit(FadeFromBlack);
  151.         startTicks := TickCount;
  152.         while TickCount < startTicks + ticks do
  153.             begin
  154.                 i := 100 - 100 * (startTicks + ticks - TickCount) div ticks;
  155.                 oe := DoGammaFade(i);
  156.  
  157.                 if Button then
  158.                     begin
  159.                         oe := DoGammaFade(100);
  160.                         Exit(FadeFromBlack);
  161.                     end;
  162.             end;
  163.         oe := DoGammaFade(100);
  164.     end; {FadeFromBlack}
  165.  
  166.  
  167.  
  168.  
  169.     function IsGammaAvailable: Boolean;
  170.         var
  171.             theGDevice: GDHandle;
  172.     begin
  173.         IsGammaAvailable := false;
  174.         if (NGetTrapAddress(kGetDeviceListTrapNum, ToolTrap) = NGetTrapAddress(_Unimplemented, ToolTrap)) then
  175.             exit(IsGammaAvailable);
  176.         theGDevice := GetDeviceList;
  177.         while (theGDevice <> nil) do
  178.             begin
  179.                 if (TestDeviceAttribute(theGDevice, screenDevice) and TestDeviceAttribute(theGDevice, noDriver)) then
  180.                     exit(IsGammaAvailable);
  181.                 if (theGDevice^^.gdType = fixedType) then
  182.                     exit(IsGammaAvailable);
  183.                 theGDevice := GetNextDevice(theGDevice);
  184.             end;
  185.         IsGammaAvailable := true; {If we made it this far then its true}
  186.     end;
  187.  
  188.  
  189.     function IsOneGammaAvailable (theGDevice: GDHandle): Boolean;
  190.     begin
  191.         IsOneGammaAvailable := false;
  192.         if (NGetTrapAddress(kGetDeviceListTrapNum, ToolTrap) = NGetTrapAddress(_Unimplemented, ToolTrap)) then
  193.             exit(IsOneGammaAvailable);
  194.         if (TestDeviceAttribute(theGDevice, screenDevice) and TestDeviceAttribute(theGDevice, noDriver)) then
  195.             exit(IsOneGammaAvailable);
  196.         if (theGDevice^^.gdType = fixedType) then
  197.             exit(IsOneGammaAvailable);
  198.         IsOneGammaAvailable := true;
  199.     end;
  200.  
  201.     function SetupGammaTools: OSErr;
  202.         var
  203.             errorCold: OSErr;
  204.             tempHdl: GlobalGammasHdl;
  205.             masterGTable: GammaTblPtr;
  206.             theGDevice: GDHandle;
  207.     begin
  208.         if (gammaUtilsInstalled = kGammaUtilsSig) then
  209.             begin
  210.                 SetupGammaTools := -1;
  211.                 exit(SetupGammaTools);
  212.             end;
  213.         gammaTables := nil;
  214.         gammaUtilsInstalled := kGammaUtilsSig;
  215.         theGDevice := GetDeviceList;
  216.         while (theGDevice <> nil) do
  217.             begin
  218.                 errorCold := GetDevGammaTable(theGDevice, masterGTable);
  219.                 if (errorCold <> 0) then
  220.                     begin
  221.                         SetupGammaTools := errorCold;
  222.                         exit(SetupGammaTools);
  223.                     end;
  224.                 tempHdl := globalGammasHdl(NewHandle(sizeof(globalGammas)));
  225.                 if (tempHdl = nil) then
  226.                     begin
  227.                         SetupGammaTools := MemError;
  228.                         exit(SetupGammaTools);
  229.                     end;
  230.                 with masterGTable^ do
  231.                     begin
  232.                         tempHdl^^.size := sizeof(GammaTbl) + gFormulaSize + (gChanCnt * gDataCnt * gDataWidth div 8);
  233.                         tempHdl^^.dataOffset := gFormulaSize;
  234.                         tempHdl^^.theGDevice := theGDevice;
  235.                     end;
  236.                 tempHdl^^.saved := GammaTblHandle(NewHandle(tempHdl^^.size));
  237.                 if (tempHdl^^.saved = nil) then
  238.                     begin
  239.                         SetupGammaTools := MemError;
  240.                         exit(SetupGammaTools);
  241.                     end;
  242.                 tempHdl^^.hacked := GammaTblHandle(NewHandle(tempHdl^^.size));
  243.                 if (tempHdl^^.hacked = nil) then
  244.                     begin
  245.                         SetupGammaTools := MemError;
  246.                         exit(SetupGammaTools);
  247.                     end;
  248.                 BlockMove(Ptr(masterGTable), Ptr(tempHdl^^.saved^), tempHdl^^.size);
  249.                 tempHdl^^.next := gammaTables;
  250.                 gammaTables := tempHdl;
  251.                 theGDevice := GetNextDevice(theGDevice)
  252.             end;
  253.         SetupGammaTools := 0;
  254.     end;
  255.  
  256.     function DoGammaFade (percent: Integer): OSErr;
  257.         var
  258.             errorCold: OSErr;
  259.             thesize, i, theNum: LongInt;
  260.             tempHdl: GlobalGammasHdl;
  261.             dataPtr: Ptr;
  262.             tempGammaTbl: GammaTblPtr;
  263.             gdp: GammaDataPtr;
  264.             tempLong: Longint;
  265.     begin
  266.         if gammaUtilsInstalled <> kGammaUtilsSig then
  267.             errorCold := SetupGammaTools;
  268.         if gammaUtilsInstalled <> kGammaUtilsSig then
  269.             begin
  270.                 DoGammaFade := -1;
  271.                 exit(DoGammaFade);
  272.             end;
  273.         tempHdl := gammaTables;
  274.         while (tempHdl <> nil) do
  275.             begin
  276.                 with tempHdl^^ do
  277.                     begin
  278.                         BlockMove(Ptr(saved^), Ptr(hacked^), size);
  279.                         tempLong := ord(@hacked^^.gFormulaData) + dataOffset;
  280.                         gdp := gammaDataPtr(ord(@hacked^^.gFormulaData) + dataOffset);
  281.                         thesize := hacked^^.gChanCnt * hacked^^.gDataCnt;
  282.                     end;
  283.                 for i := 0 to thesize - 1 do
  284.                     begin
  285.                         theNum := gdp^[i];
  286.                         theNum := (theNum * percent) div 100;
  287.                         gdp^[i] := theNum;
  288.                     end;
  289.                 errorCold := SetDevGammaTable(tempHdl^^.theGDevice, tempHdl^^.hacked^);
  290.                 if (errorCold <> 0) then
  291.                     begin
  292.                         DoGammaFade := errorCold;
  293.                         exit(DoGammaFade);
  294.                     end;
  295.                 tempHdl := tempHdl^^.next;
  296.             end;
  297.         DoGammaFade := 0;
  298.     end;
  299.  
  300.     function DoOneGammaFade (theGDevice: GDHandle; percent: Integer): OSErr;
  301.         var
  302.             errorCold: OSErr;
  303.             thesize, i, theNum: LongInt;
  304.             tempHdl: GlobalGammasHdl;
  305.             gdp: GammaDataPtr;
  306.     begin
  307.         if gammaUtilsInstalled <> kGammaUtilsSig then
  308.             errorCold := SetupGammaTools;
  309.         if gammaUtilsInstalled <> kGammaUtilsSig then
  310.             begin
  311.                 DoOneGammaFade := -1;
  312.                 Exit(DoOneGammaFade);
  313.             end;
  314.         tempHdl := gammaTables;
  315.         while ((tempHdl <> nil) and (theGDevice <> tempHdl^^.theGDevice)) do
  316.             tempHdl := tempHdl^^.next;
  317.         with tempHdl^^ do
  318.             begin
  319.                 BlockMove(Ptr(saved^), Ptr(hacked^), size);
  320.                 gdp := gammaDataPtr(ord(@hacked^^.gFormulaData) + dataOffset);
  321.                 thesize := hacked^^.gChanCnt * hacked^^.gDataCnt;
  322.             end;
  323.         for i := 0 to thesize - 1 do
  324.             begin
  325.                 theNum := gdp^[i];
  326.                 theNum := (theNum * percent) div 100;
  327.                 gdp^[i] := theNum;
  328.             end;
  329.         errorCold := SetDevGammaTable(tempHdl^^.theGDevice, tempHdl^^.hacked^);
  330.         DoOneGammaFade := errorCold;
  331.     end;
  332.  
  333.     function DisposeGammaTools: OSErr;
  334.         var
  335.             tempHdl, nextHdl: GlobalGammasHdl;
  336.     begin
  337.         if gammaUtilsInstalled <> kGammaUtilsSig then
  338.             begin
  339.                 DisposeGammaTools := -1;
  340.                 Exit(DisposeGammaTools);
  341.             end;
  342.         tempHdl := gammaTables;
  343.         while (tempHdl <> nil) do
  344.             begin
  345.                 HLock(Handle(tempHdl));
  346.                 with tempHdl^^ do
  347.                     begin
  348.                         nextHdl := next;
  349.                         DisposeHandle(Handle(saved));
  350.                         DisposeHandle(Handle(hacked));
  351.                         HUnLock(Handle(tempHdl));
  352.                         DisposeHandle(Handle(tempHdl));
  353.                         tempHdl := nextHdl;
  354.                     end;
  355.             end;
  356.         gammaUtilsInstalled := '    ';
  357.         DisposeGammaTools := 0;
  358.     end;
  359.  
  360.     function GetDevGammaTable (theGDevice: GDHandle; var theTable: GammaTblPtr): OSErr;
  361.         var
  362.             errorCold: OSErr;
  363.             myCPB: ParmBlkPtr;
  364.     begin
  365.         theTable := nil;
  366.         if not IsOneGammaAvailable(theGDevice) then
  367.             begin
  368.                 GetDevGammaTable := -1;
  369.                 exit(GetDevGammaTable);
  370.             end;
  371.         myCPB := ParmBlkPtr(NewPtrClear(sizeof(ParamBlockRec)));
  372.         if (myCPB = nil) then
  373.             begin
  374.                 GetDevGammaTable := MemError;
  375.                 exit(GetDevGammaTable);
  376.             end;
  377.         myCPB^.csCode := cscGetGamma;
  378.         myCPB^.ioCRefNum := theGDevice^^.gdRefNum;
  379.         myCPB^.csParam[0] := HiWord(longint(@theTable));
  380.         myCPB^.csParam[1] := LoWord(longint(@theTable));
  381. {$IFC UNDEFINED THINK_PASCAL}
  382.         errorCold := PBStatusSync(myCPB);
  383. {$ELSEC}
  384.         errorCold := PBStatus(myCPB, false);
  385. {$ENDC}
  386.         DisposePtr(Ptr(myCPB));
  387.         GetDevGammaTable := errorCold;
  388.     end;
  389.  
  390.     function SetDevGammaTable (theGDevice: GDHandle; var theTable: GammaTblPtr): OSErr;
  391.         var
  392.             myCPB: ParmBlkPtr;
  393.             errorCold: OSErr;
  394.             cTab: CTabHandle;
  395.             saveGDevice: GDHandle;
  396.     begin
  397.         if not IsOneGammaAvailable(theGDevice) then
  398.             begin
  399.                 SetDevGammaTable := -1;
  400.                 exit(SetDevGammaTable);
  401.             end;
  402.         myCPB := ParmBlkPtr(NewPtrClear(sizeof(ParamBlockRec)));
  403.         if (myCPB = nil) then
  404.             begin
  405.                 SetDevGammaTable := MemError;
  406.                 exit(SetDevGammaTable);
  407.             end;
  408.         myCPB^.csCode := cscSetGamma;
  409.         myCPB^.ioCRefNum := theGDevice^^.gdRefNum;
  410.         myCPB^.csParam[0] := HiWord(longint(@theTable));
  411.         myCPB^.csParam[1] := LoWord(longint(@theTable));
  412. {$IFC UNDEFINED THINK_PASCAL}
  413.         errorCold := PBControlSync(myCPB);
  414. {$ELSEC}
  415.         errorCold := PBControl(myCPB, false);
  416. {$ENDC}
  417.         if (errorCold = 0) then
  418.             begin
  419.                 saveGDevice := GetGDevice;
  420.                 SetGDevice(theGDevice);
  421.                 cTab := theGDevice^^.gdPMap^^.pmTable;
  422.                 SetEntries(0, cTab^^.ctSize, cTab^^.ctTable);
  423.                 SetGDevice(saveGDevice);
  424.             end;
  425.         DisposePtr(Ptr(myCPB));
  426.         SetDevGammaTable := errorCold;
  427.     end;
  428.  
  429. end.